package com.example.meetsmart.service;

import com.example.meetsmart.model.Booking;
import com.example.meetsmart.model.Room;
import com.example.meetsmart.repository.BookingRepository;
import com.example.meetsmart.repository.RoomRepository;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReportService {
    private final BookingRepository bookingRepository;
    private final RoomRepository roomRepository;

    public ReportService(BookingRepository bookingRepository, RoomRepository roomRepository) {
        this.bookingRepository = bookingRepository;
        this.roomRepository = roomRepository;
    }

    public byte[] generateRoomUtilizationReport(LocalDate startDate, LocalDate endDate) throws FileNotFoundException, JRException {
        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);

        List<Room> rooms = roomRepository.findByIsActiveTrue();
        List<Booking> bookings = bookingRepository.findBookingsBetween(startDateTime, endDateTime);

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("startDate", startDate.toString());
        parameters.put("endDate", endDate.toString());

        File file = ResourceUtils.getFile("classpath:reports/room_utilization.jrxml");
        JasperReport jasperReport = JasperCompileManager.compileReport(file.getAbsolutePath());

        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(rooms);
        parameters.put("roomsDataSource", dataSource);

        Map<Long, List<Booking>> bookingsByRoom = new HashMap<>();
        for (Room room : rooms) {
            List<Booking> roomBookings = bookings.stream()
                    .filter(b -> b.getRoom().getId().equals(room.getId()))
                    .toList();
            bookingsByRoom.put(room.getId(), roomBookings);
        }
        parameters.put("bookingsByRoom", bookingsByRoom);

        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());
        return JasperExportManager.exportReportToPdf(jasperPrint);
    }

    public byte[] generateUserBookingReport(Long userId, LocalDate startDate, LocalDate endDate) throws FileNotFoundException, JRException {
        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);

        List<Booking> userBookings = bookingRepository.findBookingsBetween(startDateTime, endDateTime)
                .stream()
                .filter(b -> b.getUser().getId().equals(userId))
                .toList();

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("startDate", startDate.toString());
        parameters.put("endDate", endDate.toString());
        parameters.put("userName", userBookings.isEmpty() ? "Unknown" : userBookings.get(0).getUser().getUsername());

        File file = ResourceUtils.getFile("classpath:reports/user_bookings.jrxml");
        JasperReport jasperReport = JasperCompileManager.compileReport(file.getAbsolutePath());

        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(userBookings);
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);

        return JasperExportManager.exportReportToPdf(jasperPrint);
    }

    public byte[] generateRoomBookingReport(Long roomId, LocalDate startDate, LocalDate endDate) throws FileNotFoundException, JRException {
        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.atTime(LocalTime.MAX);

        Room room = roomRepository.findById(roomId)
                .orElseThrow(() -> new RuntimeException("Room not found"));

        List<Booking> roomBookings = bookingRepository.findBookingsBetween(startDateTime, endDateTime)
                .stream()
                .filter(b -> b.getRoom().getId().equals(roomId))
                .toList();

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("startDate", startDate.toString());
        parameters.put("endDate", endDate.toString());
        parameters.put("roomName", room.getName());

        File file = ResourceUtils.getFile("classpath:reports/room_bookings.jrxml");
        JasperReport jasperReport = JasperCompileManager.compileReport(file.getAbsolutePath());

        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(roomBookings);
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);

        return JasperExportManager.exportReportToPdf(jasperPrint);
    }
}